﻿<?xml version="1.0" encoding="utf-8" ?>
<html><head>
  ARnActorDoc
  ARn 2015/03/24
</head>
<body>
  <p>
  Cette librairie prend ses bases sur le modèle acteur tel que définit par Gubpta (Référence ...).
  Pour ARnActor, un acteur de l'Actor Model est définit comme suit :
    - un acteur est un processus informatique qui à la réception d'un message verra son Behavior s'exécuter.
    - un acteur lorqu'il reçoit un message correspondant à l'un de ses Behaviors peut 
      - créer un autre acteur
      - envoyer un message à un acteur qu'il connait
      - changer de Behavior
   </p>
  <p>
   ARnActor permet de créer de tels actors en langage C#. Pour ARnActor, un acteur est simplement un objet implémentant l'interface IActor, et c'est tout.
   La plupart des acteurs créés sont dérivés d'un acteur de base actActor.
   ARnActor fournit l'architecture logicielle de gestion des messages entre acteurs, et de l'exécution des acteurs.
   </p>
  <p>
   L'acteur le plus simple de ARnActor est appelé actActor. C'est un acteur complet mais dépourvu de tout aspect comportemental : il ne possède pas encore de Behavior.
   Il dispose par contre d'une mailbox.
   </p>
  <p>
   Pour pouvoir faire quelque chose d'utile avec cet actActor, il faut lui associer un Behavior.
   
   Par exemple,
      ...
      var actor = new actActor(new bhvBehaviorConsole()) ;
   Avec cette simple déclaration, on peut ensuite écrire :
    ...
     SendMessageTo("Hello world!",actor) ;
     ...
     le résultat s'affichera bien évidemment sur la fenêtre de sortie.
     ...
     Un acteur peut faire des choses un peu plus utile, par exemple :
     ...
     var collection = new actCollection() ;
     ...
     </p>
  <p>
     Il est alors possible de stocker des éléments dans cette collection :
     ...
     SendMessageTo("quelque chose à stocker",collection) ;
     ...
     et on peut le faire depuis n'importe quel acteur, sans préoccupation de verrouillage ou multithreading etc ...
     actCollection() étant un acteur, cet acteur garantit son exécution dans un seul thread à la fois.
     ...
     Comme c'est une collection, on peut l'utiliser avec Linq, par exemple ...
     ...
     int qtt = collection.Count() renverra le nombre d'éléments présent dans la collection.
     ...
     </p>
  <p>
     Les acteurs d'un même processus sont hébergés dans un Shard. Ce shard, un acteur lui aussi, fournit quelques fonctions utiles comme la mise à disposition
     de services communs.
     Comme un acteur ne peut communiquer qu'avec des acteurs connus, il existe un acteur spécifique qui permet de rendre publique à tout acteur un répertoire d'acteur identifié par un alias.
     </p>
  <p>
     Par exemple :
      var actorService = new actActor() ;
      ...
      actDirectory.Register(actorService,"ActorService") ;
      va rendre publique l'acteur actorService.
      ...
     </p>
  <p>
  Typiquement actDirectory comprend au moins 2 services : lui-même et console.
  De plus, afin de faciliter certaines tâches d'appels, un acteur est disponible pour faciliter certains appels : actByName
  Par exemple :
  actByName.SendByName(message,"Service") ; permet d'envoyer le message à un service en connaissant uniquement son nom.
</p>
  <p>
  Plusieurs shards peuvent coexister sur une même machine ou sur un réseau, et peuvent communiquer entre eux.
  Par exemple, un message peut être envoyé depuis un acteur A situé sur le Shard 1 vers un acteur B situé sur le shard 2.
  Il est notamment possible de découvrir les services d'un Shard depuis un acteur situé sur un autre shard.
</p>
  <p>
  ARnActor est rapide : il essayera de transmettre les messages d'un acteur à un autre en permanence.

  Par exemple, un anneau de 10000 acteurs s'échangeant 10000 messages s'exécute en à peu près 12s sur un I7 récent.
  Soit 100 000 000 de messages échangés en 12 s, plus de 8 000 000 messages par seconde.
  </p>
  <p>
  Le code :
  ...
  new actRing(10000,10000) ;
  ...
  correspond à cette performance.
  Il peut être intéressant de regarder en même temps quelques indicateurs de performances mémoire ou processeur.
  Notamment, sur un I7 4 coeurs, l'occupation du CPU est réelle, mais le système reste disponible.
  Le test similaire suivant :
  ...
  new actRing(100000,100000) ;
  ...
  va prendre beaucoup plus de temps, mais n'échouera pas si vous disposez d'assez de mémoire.
  Sur un I7 4 coeurs récent, pourvu de 16 Go de mémoire, compter 24 minutes environ, un certain manque de linéarité étant lié au Garbage Collecting.
  Il faut en effet stocker les acteurs et les messages.
</p>
  <p>
    Un acteur est constitué de :
    une mailbox
    un behavior
    La mailbox contient les messages non encore traités, le behavior comprend la liste des comportements réagissant à ces messages.
    A réception d'un message, un acteur va :
    (1) extraire le message de la file d'attente des messages en réception
    (2) pour chaque Behavior, si le pattern (une fonction qui renvoie un boolean) correspond, alors le comportement sera appliqué. Sinon on passe au behavior suivant.
  </p>
  <P>
    Donc :
    un behavior NULL ne prendra aucun message, l'acteur est fait mort.
    un behavior avec un pattern toujours VRAI prendra tous les messages.
    Si un message ne peut être utilisé par un pattern, il est mis dans une file d'attente des non traités.
  </P>
</body>
</html>
